"""
经济日历数据模块
获取宏观经济日历数据
注意：该接口需验证后使用，仅支持实盘服务
"""
import time
from typing import Dict, List, Optional
from datetime import datetime, timedelta
from loguru import logger

try:
    import okx.PublicData as PublicData
except ImportError:
    logger.warning("okx SDK未安装，请运行: pip install okx")
    PublicData = None


class EconomicCalendarManager:
    """经济日历数据管理器"""
    
    # 限速配置：1次/5s
    RATE_LIMIT_REQUESTS = 1
    RATE_LIMIT_WINDOW = 5.0  # 秒
    
    # 重要性级别映射
    IMPORTANCE_LEVELS = {
        "0": "低",
        "1": "中",
        "2": "高",
    }
    
    def __init__(self, api_key: str = "", secret_key: str = "", passphrase: str = ""):
        """
        初始化经济日历数据管理器
        注意：该接口需要API认证，仅支持实盘
        
        Args:
            api_key: API密钥
            secret_key: 密钥
            passphrase: 口令
        """
        if PublicData is None:
            raise ImportError("okx SDK未安装，请运行: pip install okx")
        
        # 该接口仅支持实盘
        flag = "0"
        
        # 初始化OKX公共数据API（需要认证）
        self.public_api = PublicData.PublicAPI(
            api_key=api_key,
            api_secret_key=secret_key,
            passphrase=passphrase,
            flag=flag
        )
        
        # 限速控制
        self.request_times: List[float] = []  # 请求时间戳列表
        
        # 数据缓存
        self.calendar_cache: Optional[List[Dict]] = None
        self.cache_expire_time: Optional[datetime] = None
        self.cache_duration = timedelta(hours=1)  # 缓存1小时
        
        logger.info("经济日历数据管理器已初始化 (仅支持实盘)")
        logger.warning("该接口需要API认证，请确保已配置正确的API密钥")
    
    def _check_rate_limit(self):
        """
        检查并执行限速
        限速规则：1次/5s (IP)
        """
        now = time.time()
        
        # 移除5秒前的请求记录
        self.request_times = [t for t in self.request_times 
                             if now - t < self.RATE_LIMIT_WINDOW]
        
        # 如果达到限速上限，等待
        if len(self.request_times) >= self.RATE_LIMIT_REQUESTS:
            oldest_request = self.request_times[0]
            wait_time = self.RATE_LIMIT_WINDOW - (now - oldest_request)
            
            if wait_time > 0:
                logger.debug(f"触发限速，等待 {wait_time:.2f} 秒")
                time.sleep(wait_time)
                # 重新计算
                now = time.time()
                self.request_times = [t for t in self.request_times 
                                     if now - t < self.RATE_LIMIT_WINDOW]
        
        # 记录本次请求
        self.request_times.append(now)
    
    def get_economic_calendar(self, region: Optional[str] = None,
                             importance: Optional[str] = None,
                             use_cache: bool = True) -> List[Dict]:
        """
        获取经济日历数据
        获取过去三个月的宏观经济日历数据
        
        Args:
            region: 地区，如 US, EU, CN 等
            importance: 重要性，0=低，1=中，2=高
            use_cache: 是否使用缓存
            
        Returns:
            经济日历数据列表，每条数据包含：
            - calendarId: 日历ID
            - date: 事件日期（毫秒时间戳）
            - region: 地区
            - event: 事件名称
            - category: 事件类别
            - importance: 重要性（0/1/2）
            - actual: 实际值
            - forecast: 预测值
            - previous: 前值
            - prevInitial: 前值初值
            - refDate: 参考日期（毫秒时间戳）
            - dateSpan: 日期跨度
            - unit: 单位
            - ccy: 货币
            - uTime: 更新时间（毫秒时间戳）
        """
        # 检查缓存
        if use_cache and self.calendar_cache is not None:
            if self.cache_expire_time and datetime.now() < self.cache_expire_time:
                logger.debug("从缓存获取经济日历数据")
                data = self.calendar_cache
                
                # 应用筛选条件
                if region:
                    data = [d for d in data if d.get("region") == region]
                if importance:
                    data = [d for d in data if d.get("importance") == importance]
                
                return data
        
        # 执行限速检查
        self._check_rate_limit()
        
        try:
            # 构建请求参数
            params = {}
            if region:
                params["region"] = region
            if importance:
                params["importance"] = importance
            
            logger.info(f"获取经济日历数据 (过去3个月)")
            result = self.public_api.get_economic_calendar(**params)
            
            # 检查响应
            if result.get("code") != "0":
                error_msg = result.get("msg", "未知错误")
                logger.error(f"获取经济日历数据失败: {error_msg}")
                raise RuntimeError(f"API错误: {error_msg}")
            
            # 提取数据
            data_list = result.get("data", [])
            logger.info(f"获取经济日历数据成功: {len(data_list)} 条")
            
            # 更新缓存
            if use_cache:
                self.calendar_cache = data_list
                self.cache_expire_time = datetime.now() + self.cache_duration
            
            return data_list
            
        except Exception as e:
            logger.error(f"获取经济日历数据异常: {e}")
            raise
    
    def get_events_by_date(self, target_date: datetime,
                          region: Optional[str] = None,
                          importance: Optional[str] = None) -> List[Dict]:
        """
        获取指定日期的经济事件
        
        Args:
            target_date: 目标日期
            region: 地区筛选
            importance: 重要性筛选
            
        Returns:
            该日期的经济事件列表
        """
        all_events = self.get_economic_calendar(region, importance)
        
        # 筛选指定日期的事件
        target_timestamp = int(target_date.timestamp() * 1000)
        target_day_start = int(target_date.replace(hour=0, minute=0, second=0).timestamp() * 1000)
        target_day_end = int(target_date.replace(hour=23, minute=59, second=59).timestamp() * 1000)
        
        events = []
        for event in all_events:
            event_date = int(event.get("date", 0))
            if target_day_start <= event_date <= target_day_end:
                events.append(event)
        
        return events
    
    def get_high_importance_events(self, region: Optional[str] = None) -> List[Dict]:
        """
        获取高重要性的经济事件
        
        Args:
            region: 地区筛选
            
        Returns:
            高重要性事件列表
        """
        return self.get_economic_calendar(region=region, importance="2")
    
    def get_events_by_region(self, region: str) -> List[Dict]:
        """
        获取指定地区的经济事件
        
        Args:
            region: 地区代码，如 US, EU, CN
            
        Returns:
            该地区的经济事件列表
        """
        return self.get_economic_calendar(region=region)
    
    def parse_event(self, event: Dict) -> Dict:
        """
        解析经济事件数据
        
        Args:
            event: 原始事件数据
            
        Returns:
            解析后的事件字典
        """
        date_ts = int(event.get("date", 0))
        ref_date_ts = int(event.get("refDate", 0))
        update_ts = int(event.get("uTime", 0))
        
        importance = event.get("importance", "0")
        importance_text = self.IMPORTANCE_LEVELS.get(importance, "未知")
        
        return {
            "calendar_id": event.get("calendarId"),
            "event_name": event.get("event"),
            "category": event.get("category"),
            "region": event.get("region"),
            "importance": importance,
            "importance_text": importance_text,
            "date": datetime.fromtimestamp(date_ts / 1000).strftime("%Y-%m-%d %H:%M:%S") if date_ts > 0 else "",
            "date_ms": date_ts,
            "ref_date": datetime.fromtimestamp(ref_date_ts / 1000).strftime("%Y-%m-%d") if ref_date_ts > 0 else "",
            "actual": event.get("actual"),
            "forecast": event.get("forecast"),
            "previous": event.get("previous"),
            "prev_initial": event.get("prevInitial"),
            "unit": event.get("unit"),
            "currency": event.get("ccy"),
            "date_span": event.get("dateSpan"),
            "update_time": datetime.fromtimestamp(update_ts / 1000).strftime("%Y-%m-%d %H:%M:%S") if update_ts > 0 else "",
        }
    
    def get_upcoming_events(self, days: int = 7, region: Optional[str] = None,
                           importance: Optional[str] = None) -> List[Dict]:
        """
        获取未来几天的经济事件
        
        Args:
            days: 未来天数
            region: 地区筛选
            importance: 重要性筛选
            
        Returns:
            未来事件列表
        """
        all_events = self.get_economic_calendar(region, importance)
        
        now = datetime.now()
        future_timestamp = int((now + timedelta(days=days)).timestamp() * 1000)
        now_timestamp = int(now.timestamp() * 1000)
        
        upcoming = []
        for event in all_events:
            event_date = int(event.get("date", 0))
            if now_timestamp <= event_date <= future_timestamp:
                upcoming.append(event)
        
        # 按日期排序
        upcoming.sort(key=lambda x: int(x.get("date", 0)))
        
        return upcoming
    
    def get_events_summary(self, region: Optional[str] = None) -> Dict:
        """
        获取经济事件统计摘要
        
        Args:
            region: 地区筛选
            
        Returns:
            统计摘要字典
        """
        events = self.get_economic_calendar(region=region)
        
        # 统计各重要性级别的事件数量
        importance_count = {"0": 0, "1": 0, "2": 0}
        for event in events:
            imp = event.get("importance", "0")
            importance_count[imp] = importance_count.get(imp, 0) + 1
        
        # 统计各地区的事件数量
        region_count = {}
        for event in events:
            reg = event.get("region", "unknown")
            region_count[reg] = region_count.get(reg, 0) + 1
        
        return {
            "total_events": len(events),
            "low_importance": importance_count["0"],
            "medium_importance": importance_count["1"],
            "high_importance": importance_count["2"],
            "regions": region_count,
        }
    
    def clear_cache(self):
        """清除缓存"""
        self.calendar_cache = None
        self.cache_expire_time = None
        logger.info("已清除经济日历缓存")
    
    def get_cache_stats(self) -> Dict:
        """
        获取缓存统计信息
        
        Returns:
            缓存统计字典
        """
        is_cached = self.calendar_cache is not None
        is_valid = False
        
        if is_cached and self.cache_expire_time:
            is_valid = datetime.now() < self.cache_expire_time
        
        return {
            "is_cached": is_cached,
            "is_valid": is_valid,
            "cached_events": len(self.calendar_cache) if self.calendar_cache else 0,
            "cache_duration_seconds": self.cache_duration.total_seconds(),
        }


# 便捷函数
def get_economic_calendar(api_key: str, secret_key: str, passphrase: str,
                         region: Optional[str] = None,
                         importance: Optional[str] = None) -> List[Dict]:
    """
    便捷函数：获取经济日历数据
    
    Args:
        api_key: API密钥
        secret_key: 密钥
        passphrase: 口令
        region: 地区
        importance: 重要性
        
    Returns:
        经济日历数据列表
    """
    manager = EconomicCalendarManager(api_key, secret_key, passphrase)
    return manager.get_economic_calendar(region, importance)


def get_high_importance_events(api_key: str, secret_key: str, passphrase: str,
                               region: Optional[str] = None) -> List[Dict]:
    """
    便捷函数：获取高重要性事件
    
    Args:
        api_key: API密钥
        secret_key: 密钥
        passphrase: 口令
        region: 地区
        
    Returns:
        高重要性事件列表
    """
    manager = EconomicCalendarManager(api_key, secret_key, passphrase)
    return manager.get_high_importance_events(region)
